#pragma once

#include <functional>
#include <string>
#include "Socket.hpp"
#include "Log.hpp"

extern Log log;

using func_t = std::function<std::string(std::string &package)>;

const uint16_t defaulport = 28080;

// 服务器的启动和运行封装
class TCPServer{
public:
    TCPServer(const uint16_t port = defaulport, func_t callback = nullptr)
    : _port(port), _callback(callback)
    {}

    void InitServer(){
        _listensock.Socket();
        _listensock.Bind(_port);
        _listensock.Listen();
        log(INFO, "Init TCPServer ... done!");
    }

    void StartServer(){
        while(true){
            std::string clientip;
            uint16_t clientport;
            int sockfd = _listensock.Accept(&clientip, &clientport);
            if(sockfd < 0){
                continue;
            }
            log(INFO, "Accept a new link, sockfd: %d, clientip: %s, clientport: %d", 
                sockfd, clientip.c_str(), clientport);

            // 提供服务--- 多进程版
            if (fork() == 0){
                // child
                _listensock.Close();
                std::string inbuffer_stream;
                while(true){
                    char buffer[128];
                    // 接收请求
                    ssize_t n = read(sockfd, buffer, sizeof(buffer));
                    if(n > 0){
                        buffer[n] = 0;
                        inbuffer_stream+=buffer;
                        log(Debug, "Debug: %s", inbuffer_stream.c_str());

                        // 处理请求 直到缓存区中没有有效报文
                        while(true){
                            std::string info = _callback(inbuffer_stream);
                            if (info.empty()){
                                break;
                            }
                            // 发送响应
                            write(sockfd, info.c_str(), info.size());
                        }
                    }
                    else if(n == 0){
                        break;
                    }
                    else{
                        break;
                    }
                }

                exit(0);
            }
            // father
            close(sockfd);
        }
    }

    ~TCPServer()
    {}
private:
    uint16_t _port;
    MySocket _listensock;
    func_t _callback;
};